package com.example.demo

import com.example.demo.instance.OddNumber1ServiceImpl
import com.example.demo.instance.OddNumberService
import groovy.sql.Sql
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll

/**
 * spock1.2版本文档，对应版本只需修改最后的版本号
 * http://spockframework.org/spock/docs/1.2
 * groovy
 * http://groovy-lang.org/documentation.html
 * @Author daFa* @create 2019/3/11 17:48
 */
class DemoApplicationSpec extends Specification {

    @Shared def url = "jdbc:h2:file:./db/h2/spock-grovvy-learn"

    /**
     * 使用h2内存数据库方能获得更加灵活的测试环境
     */
    @Shared def sql = Sql.newInstance(
                 url: url,
                 user:'sa',
                 password:'',
                 driver:'org.h2.Driver',
                 cacheStatements: true
             )
    @Shared def map
    /**
     * 在每个特征方法之前运行
     */
    def setup() {}
    /**
     * 在每个要素方法之后运行
     */
    def cleanup() {}
    /**
     * 运行一次 - 在最后一个特征方法之后
     */
    def cleanupSpec() {}

    /**
     * 运行一次 - 在第一个特征方法之前
     * setupSpec()并cleanupSpec() 可能不引用实例字段，除非它们注释@Shared。
     * @return
     */
    def setupSpec(){
       map = [name: 'Gromit', likes: 'cheese', id: 1234]
    }

    /**
     * 特征方法
     * 有6种模块：given，when，then，expect，cleanup，和where块
     * @return
     */
    def "The value of key is equal"(){
        //条件
        when:
            map.put("test","test123")
        //预期结果,相当于断言
        then:
            map.test == "test1231"
    }

    /**
     * 更简单的条件与预期
     * @Unroll 可以生成多个测试
     */
    @Unroll
    def "The value corresponding to #key is #value"(){
        expect:
            map.get(key)==value
        where:
//            key || value
//            "name" || "Gromit"
//            "likes" || "cheese"
//            另一种写法
            key<<["name","likes"]
            value<<["Gromit","cheese"]
    }

    /**
     * 处理预期异常
     */
    def "Capture exception"(){
        //条件
        when:
            1/0
        //预期结果,相当于断言
        then:
            //notThrown()  // 表示没有异常抛出
            ArithmeticException e = thrown()
            e.printStackTrace()
            //def e1 = thrown(ArithmeticException)
            //thrown(ArithmeticException)
    }

    /**
     * 是否为奇数
     * @return
     */
    @Unroll
    def "test #i isOdd() is #result"() {
        OddNumberService odd1 = new OddNumber1ServiceImpl()
        expect:
            odd1.isOdd(i)==result
        where:
            i || result
            1 || true
            2 || false

    }

    /**
     * 使用文件数据库判断大小
     * MAX_DATA 字段顺序PK_ID,FIRST_NUMBER,SECOND_NUMBER,THIRD_NUMBER
     * 其中做比较的是后3个字段而*会查出所有字段因此使用_来做占位符
     */
    def "maximum of two numbers"() {
        expect:
            Math.max(a, b) == c
        where:
        [_,a, b, c] << sql.rows("select * from MAX_DATA;")
    }
}
